-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PaletteEdit: improve unit tests #57645
Conversation
} ) | ||
); | ||
|
||
await waitFor( () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
onChange
is debounced, so we need to use waitFor
. It appears to have been debounced for performance improvements. See #40285.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To better mimic actual user behavior, it might be better to click the "Done" button rather than do a wait for the onChange
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think onChange
is called because the "Done" button only clears the internal editing state. Strictly speaking, this button should probably be called "Back" or "Exit Edit Mode"...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair point.
it( 'opens color selector for color palettes', () => { | ||
render( <PaletteEdit { ...defaultProps } /> ); | ||
fireEvent.click( screen.getByLabelText( 'Color: Base' ) ); | ||
expect( screen.getByLabelText( 'Hex color' ) ).toBeInTheDocument(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test should be covered by the "can update color palette value" test.
await user.selectOptions( typeSelectElement, 'radial-gradient' ); | ||
|
||
await waitFor( () => { | ||
expect( defaultProps.onChange ).toHaveBeenLastCalledWith( [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Somehow I had to use toHaveBeenLastCalledWith
here. Where I used toHaveBeenCalledTimes
, received number of calls was 5, so maybe that has something to do with it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is because we're reusing the jest.fn()
mock that was set on defaultProps.onChange
. We would need to do a reset between tests (e.g. jest.resetAllMocks()
in a afterEach()
) if we wanted to do it that way. Or we usually just use a fresh mock for each test that needs one:
const onChange = jest.fn();
render( <PaletteEdit { ...defaultProps } onChange={ onChange } /> );
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for adding test coverage!
} ) | ||
); | ||
|
||
await waitFor( () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To better mimic actual user behavior, it might be better to click the "Done" button rather than do a wait for the onChange
.
} ); | ||
} ); | ||
|
||
it( 'can not add a new palette', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it( 'can not add a new palette', () => { | |
it( 'can not add new colors when `canOnlyChangeValues` is enabled', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe it's important to check both aspects — either in the same test, or in two separate tests. One checks that our public APIs work as expected, the other one tests that the component works as intended for the end user.
We could technically omit the onChange
check if the component is tested in controlled mode, because if onChange
didn't work as expected, the component wouldn't work for the end user either.
But I still prefer to test onChange
(and the number of times it's been called) because in my experience it's also a great proxy for other undetected issues.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. Not a blocker for this particular PR though.
name: 'Show details', | ||
} ) | ||
); | ||
await user.click( screen.getByText( 'Primary' ) ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a great example of our tests doubling as accessibility tests. The fact that there's no labeled button to click means that this part of the UI is not accessible. Let's fix this in a follow-up.
Co-authored-by: Lena Morita <[email protected]>
Co-authored-by: Lena Morita <[email protected]>
Co-authored-by: Lena Morita <[email protected]>
Co-authored-by: Lena Morita <[email protected]>
Co-authored-by: Lena Morita <[email protected]>
Co-authored-by: Lena Morita <[email protected]>
Co-authored-by: Lena Morita <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not much to add on top of Lena's comment, but still wanted to thank you for the great work so far!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚀
Thank for working on this! I just noticed in trunk the
One option could be using diff --git a/packages/components/src/palette-edit/test/index.tsx b/packages/components/src/palette-edit/test/index.tsx
index 31b712225a..9c3cb14a6b 100644
--- a/packages/components/src/palette-edit/test/index.tsx
+++ b/packages/components/src/palette-edit/test/index.tsx
@@ -176,11 +176,13 @@ describe( 'PaletteEdit', () => {
name: 'Color options',
} )
);
- expect(
- screen.getByRole( 'button', {
- name: 'Reset colors',
- } )
- ).toBeVisible();
+ await waitFor( () => {
+ expect(
+ screen.getByRole( 'button', {
+ name: 'Reset colors',
+ } )
+ ).toBeVisible();
+ } );
} );
it( 'does not show a reset colors option when `canReset` is disabled', async () => {
@@ -192,11 +194,13 @@ describe( 'PaletteEdit', () => {
name: 'Color options',
} )
);
- expect(
- screen.queryByRole( 'button', {
- name: 'Reset colors',
- } )
- ).not.toBeInTheDocument();
+ await waitFor( () => {
+ expect(
+ screen.queryByRole( 'button', {
+ name: 'Reset colors',
+ } )
+ ).not.toBeInTheDocument();
+ } );
} );
it( 'calls the `onChange` with the new color appended', async () => { What do you think? 🙂 |
Thank you for noticing 🙇
To me, this approach makes sense.
|
Preparation for solving #57309
What?
This PR updates the unit tests for the
PaletteEdit
component to cover as many scenarios as possible.Why?
To prevent regressions and bugs and to clarify component specifications.
How?
I wrote the tests to cover as many scenarios as possible based on the current specifications.
Testing Instructions
Run
npm run test:unit packages/components/src/palette-edit/test/index.tsx